/**
 * @author: giscafer ,https://github.com/giscafer
 * @date: 2020-05-16 08:54:46
 * @description: nightmare 爬取数据
 */

"use strict";
const Nightmare = require("nightmare");
const Xvfb = require("xvfb");
const request = require("superagent");
const URL = "https://live.leisu.com/";
const statsApi = "https://api.leisu.com/api/v2/match/stats?id=";

async function crawlerGamesInfo({ notStartChecked }) {
  const close = await xvfb();
  const nightmare = Nightmare({ show: false }); // show设置为true，可以看到弹出浏览器出来
  return new Promise((resolve, reject) => {
    nightmare
      .goto(URL)
      .wait("table#list tr.dd-live-title")
      .evaluate(async notStartChecked => {
        let lives = [];
        let notStart = [];
        const errorDataIds = [];
        const dataIds = [];
        const MAX_GAME_COUNT = 100; //  最大比赛数量

        /*  const matchReg = str => {
          let reg = /<\/?.+?\/?>/g;
          return str.replace(reg, "");
        }; */
        const getInnerTextByCls = (element, selector) => {
          const el = element.querySelector(selector);
          if (el && typeof el.innerText === "string") {
            return el.innerText.replace(/\\n/g, "").trim();
          }
          return "";
        };

        const timeout = ms => {
          return new Promise(resolve => {
            setTimeout(() => {
              resolve();
            }, ms);
          });
        };

        const children = document.querySelectorAll("tbody tr.dd-item");
        // 一天应该不会有MAX_GAME_COUNT场，这里做个性能
        const len =
          children.length >= MAX_GAME_COUNT ? MAX_GAME_COUNT : children.length;
        errorDataIds.push(len);

        for (let i = 0; i < len; i++) {
          const c = children[i];
          if (!c) continue;
          const dataId = c.getAttribute("data-id");
          if (dataId) {
            try {
              const eventName = getInnerTextByCls(c, ".lab-events .event-name");
              let eventIcon = "";
              const iconStyleEl = c.querySelector(".lab-events .event-icon");
              if (iconStyleEl) {
                eventIcon = iconStyleEl.style.backgroundImage;
              }
              const beginTime = getInnerTextByCls(c, ".lab-time");

              const homeTeam = getInnerTextByCls(c, ".lab-team-home .name");
              const guestTeam = getInnerTextByCls(c, ".lab-team-away .name");
              const half = getInnerTextByCls(c, ".lab-half") || "-";
              const corner = getInnerTextByCls(c, ".lab-corner") || "-";
              const score =
                getInnerTextByCls(c, ".lab-score .color-red") || "-";

              // TODO: 不知道为什么获取不到时间
              let status = "-";
              // let labstatusEl = c.querySelector("td.lab-status");
              let labstatusEl = c.querySelector("td.lab-status span.children");
              if (labstatusEl) {
                // status = matchReg(labstatusEl.innerHTML);
                status = labstatusEl.innerText;
              } else {
                await timeout(1300); // 封装一个重试方法，可能需要重试两次
                let labstatusEl =
                  c.querySelector("td.lab-status span.children") || {};
                status = labstatusEl.innerText || "-";
              }
              let newObj = {
                dataId,
                eventIcon,
                eventName,
                beginTime,
                status,
                homeTeam,
                guestTeam,
                half,
                score,
                corner
              };
              // 区分完成和未完成
              if (
                (labstatusEl && labstatusEl.innerText === "未") ||
                c.querySelector(".lab-status.no-start")
              ) {
                if (notStartChecked) {
                  notStart.push(newObj);
                }
              } else {
                lives.push(newObj);
              }

              // dataIds.push(dataId);
            } catch (e) {
              // reject(e);
              console.log("nightmare:evaluate", e);
              errorDataIds.push(dataId);
            }
          } else {
            const classList = Array.from(c.classList);
            if (classList.indexOf("dd-finished-title") > -1) {
              break;
            }
            /* const classList = Array.from(c.classList);
            // 未开始的比赛
            if (classList.indexOf("dd-notStart-title") > -1) {
              dataIds.push(dateStr);
              lives = [...result];
              result = [];
            } else if (classList.indexOf("dd-finished-title") > -1) {
              notStart = [...result];
              result = [];
              break;
            } else if (
              classList.indexOf("day-label") > -1 &&
              classList.indexOf(`dd-day-label-${dateStr}`) > -1
            ) {
              const nextTr =
                c.nextSibling.querySelector("td.lab-status span.children") ||
                {};
              if (nextTr.innerText === "未") {
                lives = [...result];
                result = [];
              } else {
                continue; // 0晨时更新当天的比赛，昨天的比赛也在进行
              }
            }*/
          }
        }
        // notStart = [...result];
        // console.log(dataIds);
        return [lives, notStart, dataIds, errorDataIds];
      }, notStartChecked)
      .end() // 结束操作
      .then(result => {
        // console.log(result);
        resolve(result);
        close();
      })
      .catch(error => {
        reject(error);
        close();
      });
  });
}

function qryStats(dataId) {
  const url = `${statsApi}${dataId}&timestramp=${Date.now()}`;
  return new Promise((resolve, reject) => {
    request.get(url).end((err, res) => {
      if (err) {
        reject(err);
      } else {
        resolve(JSON.parse(res.text));
      }
    });
  });
}

// xvfb wrapper
function xvfb(options) {
  if (process.env.container === "linux") {
    var xvfb = new Xvfb(options);

    function close() {
      return new Promise((resolve, reject) => {
        xvfb.stop(err => (err ? reject(err) : resolve()));
      });
    }

    return new Promise((resolve, reject) => {
      xvfb.start(err => (err ? reject(err) : resolve(close)));
    });
  }
  const cb = () => {};
  return new Promise(resolve => {
    resolve(cb);
  });
}

// try/catch helper
async function poss(promise) {
  try {
    const result = await promise;
    return [null, result];
  } catch (err) {
    return [err, null];
  }
}

/* function test() {
  crawlerGamesInfo()
    .then(result => {
      console.log(result);
    })
    .catch(e => {
      console.log(e);
    });
}
test(); */
module.exports = { crawlerGamesInfo, qryStats };
